package com.ssh.demo.netty;

import com.ssh.demo.config.NettyConfig;
import com.ssh.demo.core.NettyServer;
import com.ssh.demo.helper.ByteArrHelper;
import com.ssh.demo.netty.handler.UdpSessionHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * @ClassName UdpNettyServer
 * @Description TODO
 * @Author ssh
 * @Date 2021/4/12 16:25
 */
@Slf4j
@Component("udp-netty")
@AllArgsConstructor
public class UdpNettyServer implements NettyServer {

    private static Channel udpChannel;
    private static EventLoopGroup masterGroup;

    private NettyConfig nettyConfig;
    private ByteArrHelper byteArrHelper;

    @Override
    public boolean start() {
        if(udpChannel != null){
            return udpChannel.isActive();
        }

        masterGroup = new NioEventLoopGroup(nettyConfig.getMasterSize());//主线程
        Bootstrap serverBootstrap = new Bootstrap();//引导对象

        serverBootstrap
                .group(masterGroup)//配置工作线程组
                .channel(NioDatagramChannel.class)//配置为NIO的socket通道
                .option(ChannelOption.SO_BROADCAST, nettyConfig.getBroadcast())//开启广播模式
                .handler(new ChannelInitializer<NioDatagramChannel>() {
                    @Override
                    protected void initChannel(NioDatagramChannel channel) throws Exception {
                        channel.pipeline().addLast("handler",new UdpSessionHandler(byteArrHelper));//业务处理类
                    }
                });
        //使用了Future来启动线程，并绑定了端口
        ChannelFuture channelFuture = serverBootstrap.bind(nettyConfig.getUdpPort());
        //以异步的方式关闭端口
        udpChannel = channelFuture.channel();
        return true;
    }

    @Override
    public boolean stop() {
        udpChannel.close();
        if (masterGroup != null) {
            masterGroup.shutdownGracefully();
        }
        return true;
    }
}
